package com.ruoyi.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.RechargeUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.system.domain.SysChannel;
import com.ruoyi.system.domain.SysOrder;
import com.ruoyi.system.domain.SysStore;
import com.ruoyi.system.mapper.SysChannelMapper;
import com.ruoyi.system.mapper.SysOrderMapper;
import com.ruoyi.system.mapper.SysStoreMapper;
import com.ruoyi.system.service.ISysChannelService;
import com.ruoyi.system.service.ISysOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 订单Service业务层处理
 * 
 * @author ruoyi
 * @date 2022-01-19
 */
@Service
public class SysOrderServiceImpl implements ISysOrderService 
{
    @Autowired
    private SysOrderMapper sysOrderMapper;

    @Autowired
    private ISysChannelService sysChannelService;

    @Autowired
    private SysChannelMapper sysChannelMapper;

    @Autowired
    private SysStoreMapper storeMapper;


    public static Logger logger = LoggerFactory.getLogger(SysOrderServiceImpl.class);

    /**
     * 查询订单
     * 
     * @param id 订单主键
     * @return 订单
     */
    @Override
    public SysOrder selectSysOrderById(Long id)
    {
        return sysOrderMapper.selectSysOrderById(id);
    }

    /**
     * 查询订单列表
     * 
     * @param sysOrder 订单
     * @return 订单
     */
    @Override
    public List<SysOrder> selectSysOrderList(SysOrder sysOrder)
    {
        return sysOrderMapper.selectSysOrderList(sysOrder);
    }

    /**
     * 新增订单
     * 
     * @param sysOrder 订单
     * @return 结果
     */
    @Override
    public int insertSysOrder(SysOrder sysOrder)
    {
        sysOrder.setCreateTime(DateUtils.getNowDate());
        return sysOrderMapper.insertSysOrder(sysOrder);
    }

    /**
     * 修改订单
     * 
     * @param sysOrder 订单
     * @return 结果
     */
    @Override
    public int updateSysOrder(SysOrder sysOrder)
    {
        sysOrder.setUpdateTime(DateUtils.getNowDate());
        return sysOrderMapper.updateSysOrder(sysOrder);
    }

    /**
     * 批量删除订单
     * 
     * @param ids 需要删除的订单主键
     * @return 结果
     */
    @Override
    public int deleteSysOrderByIds(String ids)
    {
        return sysOrderMapper.deleteSysOrderByIds(Convert.toStrArray(ids));
    }
    /**
     * 批量补单订单
     *
     * @param ids 需要补单的订单主键
     * @return 结果
     */
    @Override
    public int batchRepairSysOrderByIds(String ids)
    {
        return sysOrderMapper.batchRepairSysOrderByIds(Convert.toStrArray(ids));
    }
    /**
     * 批量撤单订单
     *
     * @param ids 需要撤单的订单主键
     * @return 结果
     */
    @Override
    public int batchCancelSysOrderByIds(String ids)
    {
        return sysOrderMapper.batchCancelSysOrderByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除订单信息
     * 
     * @param id 订单主键
     * @return 结果
     */
    @Override
    public int deleteSysOrderById(Long id)
    {
        return sysOrderMapper.deleteSysOrderById(id);
    }

    /**
     * 设置已经充值过的平台  必须在设置 realRechargePlat 后调用
     * @return
     */
    private void setHasRechargePlat(SysOrder sysOrder){
        Integer currenHasRechargeChannelId = sysOrder.getRealRechargePlat();
        String hasRechargePlat = sysOrder.getHasRechargePlat();
        if(StrUtil.isEmpty(hasRechargePlat)){
            sysOrder.setHasRechargePlat(String.valueOf(currenHasRechargeChannelId));
        }else {
            sysOrder.setHasRechargePlat(sysOrder.getHasRechargePlat()+","+currenHasRechargeChannelId);
        }
    }

    @Override
    @Transactional
    public void bathRecharge(List<SysOrder> orderList)throws Exception{
        Map map = null;
        String bathNo = UUID.randomUUID().toString();
        for (SysOrder sysorder:orderList) {
            map = new HashMap();
            map.put("storeCode",sysorder.getStoreCode());
            map.put("storeOrderNo",sysorder.getStoreOrderNo());
            List<SysOrder> list = sysOrderMapper.checkStoreOrder(map);
            if(!CollectionUtils.isEmpty(list)){
                logger.info("存在重复的订单号："+sysorder.getStoreCode()+"_"+sysorder.getStoreOrderNo());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new Exception("存在重复的订单号："+sysorder.getStoreCode()+"_"+sysorder.getStoreOrderNo());
            }else{
                int random = (int) (Math.random() * 100000) % 100;
                sysorder.setSysOrderNo(String.valueOf(System.currentTimeMillis())+""+random);
                sysorder.setSysOrderStatus(0); //待充值
                sysorder.setSysOrderStatusApi(0); //0默认。商家提交的数据，还未调用渠道充值
                sysorder.setBatchNo(bathNo); //批次号
                sysOrderMapper.insertSysOrder(sysorder);
            }
        }
    }

    @Override
    public List<SysOrder> getNeedRechargeOrderList() {
        return null;
    }

    @Override
    @Transactional
    public void doRequestChannelRecharge() {
        int pageSize = 100;
        int pageNo = 0;
        boolean flag = true;
        Map param = new HashMap();

        SysChannel search = new SysChannel();
        search.setIsLock(0);
        List<SysChannel> channelList = sysChannelMapper.selectSysChannelList(search);
        //1:盈华  2：欧飞
        while (flag){
            param.put("startIndex",pageNo*pageSize);
            param.put("pageSize",pageSize);
            List<SysOrder> orderList = sysOrderMapper.getNeedRechargeOrderList(param);
            if(CollectionUtils.isEmpty(orderList)){
                flag = false;
            }else{
                for (SysOrder sysOrder:orderList){
                    SysChannel sysChannel = sysChannelService.getNextChannelObj(channelList,sysOrder);
                    if(sysChannel == null){
                        flag = false;
                        logger.info("<<<<<<<<<<<<<<<<<<<<<<<没有可用的渠道<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
                        break;
                    }
                    SysStore sysStore = storeMapper.checkStoreByCode(sysOrder.getStoreCode());
                    doRechargeChannel(sysChannel,sysOrder,sysStore);
                }
            }
        }
    }


    /**
     * 真实调用渠道充值
     * @param sysChannel
     * @param sysOrder
     */
    public void doRechargeChannel (SysChannel sysChannel,SysOrder sysOrder,SysStore sysStore){

        //1:盈华  2：欧飞
        if(sysChannel.getId() ==1){
            Map resultMap = RechargeUtils.doYHPay(sysOrder.getUserMobile(),sysOrder.getSysOrderNo(),String.valueOf(sysOrder.getUserAmount()));
            if(resultMap == null || resultMap.get("code") == null){
                logger.info("<<<<<<<<<<<<<<<<<<<<请求盈华充值接口失败<<<<<<<<<<<<<<<<<<<<<<<<");
                return;
            }
            Integer code =Integer.parseInt( resultMap.get("code").toString());
            String msg =resultMap.get("msg")!= null ?  resultMap.get("msg").toString() : "";
            //200 成功 ,其他失败
            if(code == 200){
                logger.info("<<<<<<<<<<<<<<<<<<<<盈华返回订单数据："+resultMap.get("data"));
                Map dataMap = JsonUtils.jsonToPojo(String.valueOf(resultMap.get("data")),Map.class);
                if(dataMap == null){
                    logger.info("<<<<<<<<<<<<<<<<<<<<盈华返回订单数据为空<<<<<<<<<<<<<<<<<<<<<<<<");
                }else{
                    sysOrder.setSysOrderStatusApi(1);
                    sysOrder.setSysOrderStatus(1);
                    sysOrder.setUpdateTime(new Date());
                    sysOrder.setChannelCode(sysChannel.getCode());
                    sysOrder.setChannelName(sysChannel.getName());
                    sysOrder.setChannelStartTime(new Date());
                    sysOrder.setOperator(""); //渠道没有返回运营商
                    sysOrder.setRealRechargePlat(sysChannel.getId().intValue());
                    sysOrder.setChannelOrderNo(String.valueOf(dataMap.get("orderID"))); //渠道订单号
                    setHasRechargePlat(sysOrder);
                    sysOrderMapper.updateSysOrder(sysOrder);

                }
            }else{
                //失败
                sysOrder.setSysOrderStatusApi(2);
                sysOrder.setSysOrderStatus(4);
                sysOrder.setUpdateTime(new Date());
                sysOrder.setChannelCode(sysChannel.getCode());
                sysOrder.setChannelName(sysChannel.getName());
                sysOrder.setChannelErrorTime(new Date());
                sysOrder.setChannelResultTime(0L);
                sysOrder.setChannelStartTime(new Date());
                sysOrder.setRealRechargePlat(sysChannel.getId().intValue());
                setHasRechargePlat(sysOrder);
                String tempMsg = sysOrder.getErrorMsg() != null ? String.valueOf(sysOrder.getErrorMsg()) : "";
                sysOrder.setErrorMsg( tempMsg+";"+msg);
                sysOrderMapper.updateSysOrder(sysOrder);

                /***********失败的时候不给回调，需要自己判断 是否还有可用的渠道，如果没有，则通知商户*************/
                isGgainDoRecharge(sysOrder,sysStore,msg);
            }

        }else if(sysChannel.getId() ==2){
            Map resultMap = RechargeUtils.doOFPay(sysOrder.getUserMobile(),sysOrder.getSysOrderNo(),String.valueOf(sysOrder.getUserAmount()));
            if(resultMap == null){
                logger.info("<<<<<<<<<<<<<<<<<<<<请求欧飞充值接口失败<<<<<<<<<<<<<<<<<<<<<<<<");
                return;
            }
            if(resultMap.get("orderinfo") != null){
                Map orderInfoMap  = JsonUtils.jsonToPojo(JsonUtils.objectToJson(resultMap.get("orderinfo")),Map.class);
                Integer retCode =Integer.valueOf(String.valueOf(orderInfoMap.get("retcode"))) ;
                //{err_msg=MD5串验证错误, retcode=1003}
                //{"orderinfo":{"cardnum":"1","game_state":"0","orderid":"S22012091","cardname":"广东移30元","cardid":"141302","sporder_id":"D202250"}}
                String channelOrderNo = orderInfoMap.get("orderid") != null ? orderInfoMap.get("orderid").toString() : "";
                String cardName = orderInfoMap.get("cardname") != null ? orderInfoMap.get("cardname").toString() : "";
                if(retCode == 1 || retCode == 9999){
                    //充值接口[请求成功]
                    sysOrder.setSysOrderStatusApi(1);
                    sysOrder.setSysOrderStatus(1);
                    sysOrder.setUpdateTime(new Date());
                    sysOrder.setChannelCode(sysChannel.getCode());
                    sysOrder.setChannelName(sysChannel.getName());
                    sysOrder.setChannelStartTime(new Date());
                    sysOrder.setOperator(cardName); //渠道没有返回运营商，只有描述信息
                    sysOrder.setRealRechargePlat(sysChannel.getId().intValue());
                    sysOrder.setChannelOrderNo(channelOrderNo); //渠道订单号
                    setHasRechargePlat(sysOrder);
                    sysOrderMapper.updateSysOrder(sysOrder);
                }else{
                    //第一次充值  请求失败
                    sysOrder.setSysOrderStatusApi(2);
                    sysOrder.setSysOrderStatus(4);
                    sysOrder.setUpdateTime(new Date());
                    sysOrder.setChannelCode(sysChannel.getCode());
                    sysOrder.setChannelName(sysChannel.getName());
                    sysOrder.setChannelErrorTime(new Date());
                    sysOrder.setChannelResultTime(0L);
                    sysOrder.setChannelStartTime(new Date());
                    sysOrder.setRealRechargePlat(sysChannel.getId().intValue());
                    setHasRechargePlat(sysOrder);
                    String errMsg = orderInfoMap.get("err_msg") != null ? String.valueOf(orderInfoMap.get("err_msg")):"未知的错误";
                    sysOrder.setErrorMsg(sysOrder.getErrorMsg()+";"+errMsg );
                    sysOrderMapper.updateSysOrder(sysOrder);

                    /***********失败的时候不给回调，需要自己判断 是否还有可用的渠道，如果没有，则通知商户*************/
                    isGgainDoRecharge(sysOrder,sysStore,errMsg);
                }
            }
        }

    }

    @Override
    public SysOrder getInfoBySysOrderNo(String sysOrderNo) {
        SysOrder sysOrder = sysOrderMapper.getInfoBySysOrderNo(sysOrderNo);
        return sysOrder;
    }

    @Override
    public SysOrder getInfoByStoreOrderNo(String storeOrderNo) {
        SysOrder sysOrder = sysOrderMapper.getInfoByStoreOrderNo(storeOrderNo);
        return sysOrder;
    }



    /***********失败的时候不给回调，需要自己判断 是否还有可用的渠道，如果没有，则通知商户*************/
    private void isGgainDoRecharge(SysOrder sysOrder,SysStore sysStore,String errMsg){
        SysChannel search = new SysChannel();
        search.setIsLock(0);
        List<SysChannel> channelList = sysChannelMapper.selectSysChannelList(search);
        SysChannel nextChannel = sysChannelService.getNextChannelObj(channelList,sysOrder);
        if(nextChannel == null){
            String callBackResult = RechargeUtils.doStoreCallBack(sysStore.getCallBackUrl(),sysOrder.getStoreOrderNo(),sysOrder.getSysOrderNo(),"500",DateUtils.dateTimeNow("yyyyMMddHHmmss"),"渠道充值失败："+errMsg);
            logger.info("商户回调结果："+callBackResult);
        }else{
            //如果还存在可用渠道，则重新发发起充值
            doRechargeChannel(nextChannel,sysOrder,sysStore);
        }
    }

}
